// SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd.
// SPDX-License-Identifier: MIT

package utils

import (
	"encoding/json"
	"fmt"
	"net"
	"os"
	"path/filepath"
	"strings"
	"time"
)

// IsUnixSocket 检查是否为Unix socket路径
func IsUnixSocket(path string) bool {
	// 绝对路径
	if strings.HasPrefix(path, "/") {
		return true
	}

	// 相对路径
	if strings.HasPrefix(path, "./") || strings.HasPrefix(path, "../") {
		return true
	}

	// 当前目录下的文件（没有冒号且没有空格的简单文件名）
	if !strings.Contains(path, ":") && !strings.Contains(path, " ") {
		// 检查是否存在该文件（socket文件）
		if _, err := os.Stat(path); err == nil {
			return true
		}
	}

	return false
}

// IsTCPAddress 检查是否为TCP地址
func IsTCPAddress(addr string) bool {
	return strings.Contains(addr, ":")
}

// DetectSocketType 检测socket类型，返回network和address
func DetectSocketType(socket string) (network, address string, err error) {
	if IsUnixSocket(socket) {
		return "unix", socket, nil
	}

	if IsTCPAddress(socket) {
		host, port, err := net.SplitHostPort(socket)
		if err != nil {
			return "", "", fmt.Errorf("invalid TCP address: %v", err)
		}
		return "tcp", fmt.Sprintf("%s:%s", host, port), nil
	}

	return "", "", fmt.Errorf("unable to detect socket type for: %s", socket)
}

// ParseSocketAddress 解析socket地址
func ParseSocketAddress(addr string) (string, string, error) {
	if IsUnixSocket(addr) {
		return "unix", addr, nil
	}

	if IsTCPAddress(addr) {
		host, port, err := net.SplitHostPort(addr)
		if err != nil {
			return "", "", fmt.Errorf("invalid TCP address: %v", err)
		}
		return "tcp", fmt.Sprintf("%s:%s", host, port), nil
	}

	return "", "", fmt.Errorf("unknown address format: %s", addr)
}

// FileExists 检查文件是否存在
func FileExists(path string) bool {
	_, err := os.Stat(path)
	return !os.IsNotExist(err)
}

// EnsureDir 确保目录存在
func EnsureDir(path string) error {
	return os.MkdirAll(path, 0755)
}

// GetConfigDir 获取配置目录
func GetConfigDir() string {
	homeDir, err := os.UserHomeDir()
	if err != nil {
		return "/etc/uwsgi_exporter"
	}
	return filepath.Join(homeDir, ".uwsgi-exporter")
}

// FormatDuration 格式化持续时间
func FormatDuration(d time.Duration) string {
	if d < time.Second {
		return fmt.Sprintf("%dms", d.Milliseconds())
	}
	if d < time.Minute {
		return fmt.Sprintf("%.2fs", d.Seconds())
	}
	return d.String()
}

// PrettyJSON 格式化JSON输出
func PrettyJSON(v interface{}) (string, error) {
	data, err := json.MarshalIndent(v, "", "  ")
	if err != nil {
		return "", err
	}
	return string(data), nil
}

// Retry 重试函数
func Retry(attempts int, sleep time.Duration, fn func() error) error {
	var err error
	for i := 0; i < attempts; i++ {
		if err = fn(); err == nil {
			return nil
		}
		if i < attempts-1 {
			time.Sleep(sleep)
		}
	}
	return err
}
